package logic

import (
	"context"
	"encoding/json"
	"feitianstudyservice/internal/types"
	_ "feitianstudyservice/internal/types"
	"fmt"
	"gitee.com/jmdvirus/jkgo/jk/jklog"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
	"io/ioutil"
)

type DBInfo struct {
	client *mongo.Client
}

type authInfo struct {
	Username string `json:"dbuser"`
	Password string `json:"dbpass"`
	Path     string `json:"dbpath"`
}

var db *DBInfo

const dbname = "feitian"
const coll_event = "event"
const coll_run = "run"

func connectDB(path string, auth authInfo) *DBInfo {
	cmd := ""
	if len(auth.Username) == 0 {
		cmd = "mongodb://" + path
	} else {
		cmd = "mongodb://" + auth.Username + ":" + auth.Password + "@" + path
	}

	dbi := DBInfo{}
	client, err := mongo.Connect(context.TODO(), options.Client().ApplyURI(cmd))
	if err != nil {
		jklog.L().Errorln(err)
	}
	dbi.client = client

	return &dbi
}

func init() {
	d, _ := ioutil.ReadFile("etc/dataservice.json")
	a := authInfo{}
	err := json.Unmarshal(d, &a)
	if err != nil {
		jklog.L().Errorln("error read json file ", err)
	}
	db = connectDB(a.Path, a)
}

func GetEventList(eventRequest types.EventRequest) *types.EventList {
	coll := db.client.Database(dbname).Collection(coll_event)
	var result types.EventList

	startTime := eventRequest.Time
	endTime := eventRequest.Time + 24*60*60*1000
	fmt.Println("startTime: ", startTime, " endTime: ", endTime)
	filter := bson.M{
		"time": bson.M{
			"$gte": startTime,
			"$lt":  endTime,
		},
	}
	cur, err := coll.Find(context.TODO(),
		filter)
	if err != nil {
		jklog.L().Errorln(err)
		return &result
	}

	err = cur.All(context.TODO(), &result.Events)
	if err != nil {
		jklog.L().Errorln(err)
		return &result
	}

	return &result
}

func EventAdd(eventRequest types.EventRequest) *types.GenResponse {
	coll := db.client.Database(dbname).Collection(coll_event)
	var result types.GenResponse
	result.Code = 200

	_, err := coll.InsertOne(context.TODO(), eventRequest)
	if err != nil {
		jklog.L().Errorln(err)
		result.Code = 501
		return &result
	}
	return &result
}

func RunAdd(runRequest types.RunRequest) *types.GenResponse {
	coll := db.client.Database(dbname).Collection(coll_run)
	var result types.GenResponse
	result.Code = 200

	filter := bson.M{
		"time":  runRequest.Time,
		"title": runRequest.Title,
		"class": runRequest.Class,
	}

	r, err := coll.Find(context.TODO(), filter)
	if err != nil {
		jklog.L().Errorln(err)
	}
	var rr []types.RunRequest
	err = r.All(context.TODO(), &rr)
	if err != nil {
		jklog.L().Errorln(err)
	}
	jklog.L().Debugln("rr len : ", len(rr))
	if len(rr) > 0 {
		updateOption := bson.M{
			"$set": bson.M{
				"state": runRequest.State,
			},
		}
		_, err := coll.UpdateOne(context.TODO(), filter, updateOption)
		if err != nil {
			jklog.L().Errorln(err)
			result.Code = 503
			return &result
		}
	} else {
		_, err := coll.InsertOne(context.TODO(), runRequest)
		if err != nil {
			jklog.L().Errorln(err)
			result.Code = 501
			return &result
		}
	}
	return &result
}

func RunGet(runRequest types.RunRequest) *types.RunRequest {
	coll := db.client.Database(dbname).Collection(coll_run)

	var result []types.RunRequest
	var no_result types.RunRequest

	startTime := runRequest.Time
	endTime := runRequest.Time + 24*60*60*1000
	filter := bson.M{
		"time": bson.M{
			"$gte": startTime,
			"$lt":  endTime,
		},
	}
	cur, err := coll.Find(context.TODO(), filter)
	if err != nil {
		jklog.L().Errorln(err)
		return &no_result
	}
	err = cur.All(context.TODO(), &result)
	if err != nil {
		jklog.L().Errorln(err)
		return &no_result
	}
	fmt.Println("result: ", len(result))
	if len(result) > 0 {
		return &result[0]
	}
	return &no_result
}
